package com.oplink.webems.modules.alarm.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.google.common.collect.Lists;
import com.oplink.webems.common.persistence.Page;
import com.oplink.webems.common.utils.DateUtils;
import com.oplink.webems.modules.alarm.dao.AlarmCurrentDao;
import com.oplink.webems.modules.alarm.dao.AlarmHistoryDao;
import com.oplink.webems.modules.alarm.dao.AlarmPropDao;
import com.oplink.webems.modules.alarm.dao.AlarmSeverDao;
import com.oplink.webems.modules.alarm.dao.AlarmStatusDao;
import com.oplink.webems.modules.alarm.dao.AlarmTypeDao;
import com.oplink.webems.modules.alarm.entity.AlarmCurrent;
import com.oplink.webems.modules.alarm.entity.AlarmHistory;
import com.oplink.webems.modules.alarm.entity.AlarmProp;
import com.oplink.webems.modules.alarm.entity.AlarmSeverity;
import com.oplink.webems.modules.alarm.entity.AlarmStatus;
import com.oplink.webems.modules.alarm.entity.AlarmType;
import com.oplink.webems.modules.cfg.dao.CfgCardDao;
import com.oplink.webems.modules.cfg.dao.CfgCardTypeDao;
import com.oplink.webems.modules.cfg.dao.CfgNeDao;
import com.oplink.webems.modules.cfg.dao.CfgNeTypeDao;
import com.oplink.webems.modules.cfg.dao.CfgSiteDao;
import com.oplink.webems.modules.cfg.dao.CfgSlotDao;
import com.oplink.webems.modules.cfg.entity.CfgNe;
import com.oplink.webems.modules.cfg.entity.CfgNeType;
import com.oplink.webems.modules.cfg.entity.CfgSite;
import com.oplink.webems.modules.cfg.entity.CfgSlot;
import com.oplink.webems.modules.sys.dao.UserDao;

/**
 * History Alarm Service
 * @author yizhang
 * @param <T>
 */
@Component
@Transactional
public class AlarmHistoryService {

	@SuppressWarnings("unused")
	private static Logger logger = LoggerFactory.getLogger(AlarmHistoryService.class);

	@Autowired
	private AlarmHistoryDao alarmhistoryDao;
	
	@Autowired
	private AlarmCurrentDao alarmcurDao;

	@Autowired
	private AlarmPropDao alarmpropDao;

	@Autowired
	private CfgSiteDao siteDao;

	@Autowired
	private CfgNeDao neDao;

	@Autowired
	private CfgCardDao cardDao;

	@Autowired
	private CfgCardTypeDao cardtypeDao;

	@Autowired
	private AlarmSeverDao seveDao;

	@Autowired
	private AlarmTypeDao atypeDao;

	@Autowired
	private CfgNeTypeDao netypeDao;

	@Autowired
	private CfgSlotDao slotDao;
	
	@Autowired
	private UserDao userDao;
	
	@Autowired
	private AlarmStatusDao stsDao;

	/**
	 * History Alarm Query
	 * @param page
	 * @param ahist
	 * @return Page<AlarmHistory>
	 */
	public Page<AlarmHistory> find(Page<AlarmHistory> page, AlarmHistory ahist) {
		DetachedCriteria dc = alarmhistoryDao.createDetachedCriteria();
		if ((ahist.getSlot() != null)) {
			if ((ahist.getSlot().getCard() != null)) {
				if (ahist.getSlot().getCard().getCardtype() != null) {
					if (ahist.getSlot().getCard().getCardtype().getId() != 0) {
						dc.createCriteria("slot").createCriteria("card").createCriteria("cardtype")
						  .add(Restrictions.eq("id", ahist.getSlot().getCard().getCardtype().getId()));
					}
				}
			}
		}
		if ((ahist.getSeverity() != null) && ahist.getSeverity().getId() != 0) {
			dc.add(Restrictions.eq("severity.id", ahist.getSeverity().getId()));
		}
		if ((ahist.getAtype() != null) && ahist.getAtype().getAid() != 0) {
			dc.add(Restrictions.eq("atype.aid", ahist.getAtype().getAid()));
		}
		if (ahist.getTimetype() != null && !ahist.getTimetype().equals("")) {
			dc.add(Restrictions.between(ahist.getTimetype(), 
					DateUtils.getStringDate(ahist.getBtimes(), "yyyy-MM-dd HH:mm"),
					DateUtils.getStringDate(ahist.getEtimes(), "yyyy-MM-dd HH:mm")));
		}
		return alarmhistoryDao.find(page, dc);
	}

	/**
	 * History Alarm Statistic
	 * @param ahist
	 * @return
	 */
	public List<Map<String, Object>> statAlarm(String btimes, String etimes, String timetype) {
		StringBuilder ql = new StringBuilder();
		List<Object> ps = Lists.newArrayList();
		ql.append("select new map(count(*) as cnt, a.severity as severity) from AlarmHistory a where 1=1");
		if (timetype != null && !timetype.equals("")) {
			ql.append(" and a." + timetype + " between ? and ?");
			ps.add(DateUtils.getStringDate(btimes, "yyyy-MM-dd HH:mm"));
			ps.add(DateUtils.getStringDate(etimes, "yyyy-MM-dd HH:mm"));
		}
		ql.append(" group by a.severity");
		List<Map<String, Object>> list = alarmhistoryDao.find(ql.toString(), ps.toArray());
		return list;
	}

	@SuppressWarnings("rawtypes")
	public List<Map> getStatMap(List<Map<String, Object>> list) {
		String cnt = "0";
		String severity = "";
		List<Map> statlist = new ArrayList<Map>();
		Map<String, String> statmap = new HashMap<String, String>();
		List<AlarmSeverity> slist = seveDao.findAllSeverity();
		List<String> elementList = new ArrayList<String>();
		if (slist != null && slist.size() > 0) {
			for (Iterator<AlarmSeverity> it = slist.iterator(); it.hasNext();) {
				AlarmSeverity seobj = (AlarmSeverity) it.next();
				elementList.add(seobj.getSeverity());
			}
		}
		if (list != null && list.size() > 0) {
			for (Iterator<Map<String, Object>> it = list.iterator(); it.hasNext();) {
				Map<String, Object> map = it.next();
				statmap = new HashMap<String, String>();
				cnt = map.get("cnt").toString();
				severity = ((AlarmSeverity) map.get("severity")).getSeverity();
				statmap.put("cnt", cnt);
				statmap.put("severity", severity);
				statlist.add(statmap);
				for (int i = 0; i < elementList.size(); i++) {
					if (severity.equals(elementList.get(i))) {
						elementList.remove(i);
					}
				}
			}
		}
		for (int i = 0; i < elementList.size(); i++) {
			statmap = new HashMap<String, String>();
			statmap.put("cnt", "0");
			statmap.put("severity", elementList.get(i));
			statlist.add(statmap);
		}
		return statlist;
	}

	public AlarmHistory getAlarmHistory(Long id) {
		AlarmHistory ahist = alarmhistoryDao.findOne(id);
		return ahist;
	}

	/**
	 * 确认后当前告警转为历史告警
	 * @param idsArr
	 * @param userid
	 */
	public void saveAlarmHist(String[] idsArr, Long userid){
		AlarmCurrent acur = null;
		AlarmStatus sts = new AlarmStatus();
		AlarmHistory ahist = new AlarmHistory();
		for (String idItem : idsArr) {
			acur = alarmcurDao.findOne(Long.parseLong(idItem));
			ahist = new AlarmHistory();
			ahist.setSlot(acur.getSlot());
			ahist.setAid(acur.getAid());
			ahist.setAidx(acur.getAidx());
			ahist.setTraptype(acur.getTraptype());
			ahist.setAtype(acur.getAtype());
			ahist.setChassis(acur.getChassis());
			ahist.setPort(acur.getPort());
			ahist.setSeverity(acur.getSeverity());
			ahist.setAdate(acur.getAdate());
			ahist.setPosition(acur.getPosition());
			ahist.setAmode(acur.getAmode());
			ahist.setSccport(acur.getSccport());
			ahist.setOpsmposition(acur.getOpsmposition());
			ahist.setRdate(DateUtils.getNowDate());
			ahist.setCdate(DateUtils.getNowDate());
			ahist.setNenode(acur.getNenode());
			ahist = alarmhistoryDao.save(ahist);
			sts = new AlarmStatus();
			sts.setStime(DateUtils.getNowDate());
			sts.setStsid(1); //1:确认；2:恢复（清除）
			sts.setUser(userDao.findOne(userid));
			sts = stsDao.save(sts);
			ahist.setStatus(sts);
			alarmhistoryDao.save(ahist);
		}
	}	
	
	
	
}
